﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using Common.Utilities;
using Common.Utilities.Dispatcher;

namespace Workflows.Components.ETL
{
	/// <summary>
	/// 
	/// </summary>
	[Serializable]
	public class DelimitedTextFileReaderInstruction:InstructionBase
	{
		#region props
		private string _TxtFilePath;
		/// <summary></summary>
		public string TxtFilePath
		{
			get
			{
				return this._TxtFilePath;
			}
			set
			{
				this._TxtFilePath = value;
			}
		}

        private string _ConnStr;
        /// <summary></summary>
        public string ConnStr
        {
            get
            {
                return this._ConnStr;
            }
            set
            {
                this._ConnStr = value;
            }
        }

        private string _SchemaName;
        /// <summary></summary>
        public string SchemaName
        {
            get
            {
                return this._SchemaName;
            }
            set
            {
                this._SchemaName = value;
            }
        }

        private string _TableName;
        /// <summary></summary>
        public string TableName
        {
            get
            {
                return this._TableName;
            }
            set
            {
                this._TableName = value;
            }
        }

        private bool _RecreateTable;
        /// <summary></summary>
        public bool RecreateTable
        {
            get
            {
                return this._RecreateTable;
            }
            set
            {
                this._RecreateTable = value;
            }
        }

        private bool _ClearExistingData;
        /// <summary></summary>
        public bool ClearExistingData
        {
            get
            {
                return this._ClearExistingData;
            }
            set
            {
                this._ClearExistingData = value;
            }
        }

		private Delimiter _ColumnDelimiter;
		/// <summary></summary>
		public Delimiter ColumnDelimiter
		{
			get
			{
				return this._ColumnDelimiter;
			}
			set
			{
				this._ColumnDelimiter = value;
			}
		}

		private int _RowNumContainingColumnHeaders;
		/// <summary></summary>
		public int RowNumContainingColumnHeaders
		{
			get
			{
				return this._RowNumContainingColumnHeaders;
			}
			set
			{
				this._RowNumContainingColumnHeaders = value;
			}
		}
		#endregion

		#region ctor
		/// <summary>
		/// 
		/// </summary>
		public DelimitedTextFileReaderInstruction():base(Guid.Empty,Guid.Empty)
		{
			this._TxtFilePath = string.Empty;
			this._ColumnDelimiter = new Delimiter(SpecialDelimiter.Tab, "");
			this._RowNumContainingColumnHeaders = 1;
		    this._ConnStr = string.Empty;
		    this._SchemaName = string.Empty;
		    this._TableName = string.Empty;
		    this._RecreateTable = true;
		    this._ClearExistingData = true;
		}

		/// <summary>
		/// constructor, all derived class must call default constructor to initialize
		/// default settings.
		/// </summary>
		public DelimitedTextFileReaderInstruction(Guid componentID, Guid jobTicketID,
			string inputFilePath, Delimiter colDelimiter, int rowNumContainingColHeaders,
            string connStr, string schemaName, string tblName, 
            bool recreateTable, bool clearExistData) 
			: base(componentID, jobTicketID)
		{
			this._TxtFilePath = inputFilePath;
			this._ColumnDelimiter = colDelimiter;
			this._RowNumContainingColumnHeaders = rowNumContainingColHeaders;
		    this._ConnStr = connStr;
		    this._SchemaName = schemaName;
		    this._TableName = tblName;
		    this._RecreateTable = recreateTable;
		    this._ClearExistingData = clearExistData;
		}
		#endregion

		#region Overrides of InstructionBase

		/// <summary>
		/// serialize settings to xml
		/// the function below is mainly for storing into database as serialized form instead of string
		/// </summary>
		public override XmlNode Serialize(ref XmlDocument xDoc, ref XmlNode parentNode)
		{
			XmlNode xNode = XmlDataUtil.AddElement(ref xDoc, parentNode, "Instruction");
			XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "Type", this.GetType().FullName);
			XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ComponentID", this.OwnerComponentID.ToString());
			XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "WorkerID", this.OwnerWorkerInstanceID.ToString());
			XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "SubmitTime", this.SubmitTime.ToString());
			XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "StartTime", this.StartTime.ToString());

			XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "TextFilePath",this.TxtFilePath);
			XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "SpecialDelimiter",
			                            Enum.GetName(typeof (SpecialDelimiter), this.ColumnDelimiter.SpecialDelimiter));
			XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "DelimiterPattern",this.ColumnDelimiter.DelimiterPattern);
			XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ColHeaderLineNumber",this.RowNumContainingColumnHeaders.ToString());
		    XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ConnStr", this.ConnStr);
		    XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "SchemaName", this.SchemaName);
		    XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "TableName", this.TableName);
		    XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "RecreateTable", this.RecreateTable.ToString());
		    XmlDataUtil.UpdateAttribute(ref xDoc, xNode, "ClearExistingData", this.ClearExistingData.ToString());

			return xNode;
		}

		/// <summary>
		/// instantiated from xml
		/// "&lt;Instructions&gt;&lt;Instruction&gt;&lt;/Instruction&gt;&lt;/Instruction&gt;", must
		/// instantiate from first child of root node
		/// </summary>
		public override InstructionBase Instantiate(XmlNode xNode)
		{
			if (xNode.Attributes.GetNamedItem("Type").Value == this.GetType().FullName)
			{
				DelimitedTextFileReaderInstruction instruction = new DelimitedTextFileReaderInstruction();
				instruction.OwnerComponentID = new Guid(XmlDataUtil.GetAttributeValue(xNode, "ComponentID", Guid.NewGuid().ToString()));
				instruction.OwnerWorkerInstanceID = new Guid(XmlDataUtil.GetAttributeValue(xNode, "WorkerID", Guid.NewGuid().ToString()));
				instruction.SubmitTime = DateTime.Parse(XmlDataUtil.GetAttributeValue(xNode, "SubmitTime", TimeUtil.DbMinTime.ToString()));
				instruction.StartTime = DateTime.Parse(XmlDataUtil.GetAttributeValue(xNode, "StartTime", TimeUtil.DbMinTime.ToString()));

				instruction.TxtFilePath = XmlDataUtil.GetAttributeValue(xNode, "TextFilePath", "");
				SpecialDelimiter specialDelimiter =
					(SpecialDelimiter)
					Enum.Parse(typeof (SpecialDelimiter),
					           XmlDataUtil.GetAttributeValue(xNode, "SpecialDelimiter", SpecialDelimiter.Tab.ToString()));
				string delimiterPattern = XmlDataUtil.GetAttributeValue(xNode, "DelimiterPattern", "");
				instruction.ColumnDelimiter=new Delimiter(specialDelimiter,delimiterPattern);
				instruction.RowNumContainingColumnHeaders = int.Parse(XmlDataUtil.GetAttributeValue(xNode, "ColHeaderLineNumber", "1"));
			    instruction.ConnStr = XmlDataUtil.GetAttributeValue(xNode, "ConnStr", "");
			    instruction.SchemaName = XmlDataUtil.GetAttributeValue(xNode, "SchemaName", "");
			    instruction.TableName = XmlDataUtil.GetAttributeValue(xNode, "TableName", "");
			    instruction.RecreateTable = bool.Parse(XmlDataUtil.GetAttributeValue(xNode, "RecreateTable", true.ToString()));
			    instruction.ClearExistingData =
			        bool.Parse(XmlDataUtil.GetAttributeValue(xNode, "ClearExistingData", true.ToString()));

				return instruction;
			}
			else
			{
				throw new Exception("Unable to instantiate component: invalid type specified in xml node");
			}
		}

		#endregion
	}
}
